home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 026-050 / 042 / mg1a / file.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  10KB  |  378 lines

  1. /*
  2.  *         File commands.
  3.  */
  4. #include    "def.h"
  5.  
  6. BUFFER    *findbuffer();
  7.  
  8. /*
  9.  * insert a file into the current buffer. Real easy - just call the
  10.  * insertfile routine with the file name.
  11.  */
  12. /*ARGSUSED*/
  13. fileinsert(f, n, k) {
  14.     register int    s;
  15.     char        fname[NFILEN];
  16.  
  17.     if ((s=ereply("Insert file: ", fname, NFILEN)) != TRUE)
  18.         return (s);
  19.     adjustcase(fname);
  20.     return (insertfile(fname, (char *) NULL)); /* don't set buffer name */
  21. }
  22.  
  23. /*
  24.  * Select a file for editing.
  25.  * Look around to see if you can find the
  26.  * fine in another buffer; if you can find it
  27.  * just switch to the buffer. If you cannot find
  28.  * the file, create a new buffer, read in the
  29.  * text, and switch to the new buffer.
  30.  */
  31. /*ARGSUSED*/
  32. filevisit(f, n, k) {
  33.     register BUFFER    *bp;
  34.     int        s;
  35.     char        fname[NFILEN];
  36.  
  37.     if ((s=ereply("Find file: ", fname, NFILEN)) != TRUE)
  38.         return (s);
  39.     if ((bp = findbuffer(fname, &s)) == NULL) return s;
  40.     curbp = bp;
  41.     if (showbuffer(bp, curwp, WFHARD) != TRUE) return FALSE;
  42.     if (bp->b_fname[0] == 0)
  43.         return (readin(fname));        /* Read it in.        */
  44.     return TRUE;
  45. }
  46.  
  47. /*
  48.  * Pop to a file in the other window. Same as last function, just
  49.  * popbuf instead of showbuffer.
  50.  */
  51. /*ARGSUSED*/
  52. poptofile(f, n, k) {
  53.     register BUFFER    *bp;
  54.     register WINDOW    *wp;
  55.     int        s;
  56.     char        fname[NFILEN];
  57.  
  58.     if ((s=ereply("Find file in other window: ", fname, NFILEN)) != TRUE)
  59.         return (s);
  60.     if ((bp = findbuffer(fname, &s)) == NULL) return s;
  61.     if ((wp = popbuf(bp)) == NULL) return FALSE;
  62.     curbp = bp;
  63.     curwp = wp;
  64.     if (bp->b_fname[0] == 0)
  65.         return (readin(fname));        /* Read it in.        */
  66.     return TRUE;
  67. }
  68.  
  69. /*
  70.  * given a file name, either find the buffer it uses, or create a new
  71.  * empty buffer to put it in.
  72.  */
  73. BUFFER *
  74. findbuffer(fname, s) char *fname; int *s; {
  75.     register BUFFER    *bp;
  76.     char        bname[NBUFN];
  77.  
  78.     adjustcase(fname);
  79.     for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
  80.         if (strcmp(bp->b_fname, fname) == 0) {
  81.             return bp;
  82.         }
  83.     }
  84.     makename(bname, fname);            /* New buffer name.    */
  85.     while ((bp=bfind(bname, FALSE)) != NULL) {
  86.         *s = ereply("Buffer name: ", bname, NBUFN);
  87.         if (*s == ABORT)        /* ^G to just quit    */
  88.             return NULL;
  89.         if (*s == FALSE) {        /* CR to clobber it    */
  90.             bp->b_fname[0] = '\0';
  91.             break;
  92.         }
  93.     }
  94.     if (bp == NULL) bp = bfind(bname, TRUE);
  95.     *s = FALSE;
  96.     return bp;
  97. }
  98.  
  99. /*
  100.  * Read the file "fname" into the current buffer.
  101.  * Make all of the text in the buffer go away, after checking
  102.  * for unsaved changes. This is called by the "read" command, the
  103.  * "visit" command, and the mainline (for "uemacs file").
  104.  */
  105. readin(fname) char *fname; {
  106.     register int        status;
  107.     register WINDOW        *wp;
  108.  
  109.     if (bclear(curbp) != TRUE)        /* Might be old.    */
  110.         return TRUE;
  111.     status = insertfile(fname, fname) ;
  112.     curbp->b_flag &= ~BFCHG;        /* No change.        */
  113.     for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  114.         if (wp->w_bufp == curbp) {
  115.             wp->w_linep = lforw(curbp->b_linep);
  116.             wp->w_dotp  = lforw(curbp->b_linep);
  117.             wp->w_doto  = 0;
  118.             wp->w_markp = NULL;
  119.             wp->w_marko = 0;
  120.         }
  121.     }
  122.     return status;
  123. }
  124. /*
  125.  * insert a file in the current buffer, after dot. Set mark
  126.  * at the end of the text inserted, point at the beginning.
  127.  * Return a standard status. Print a summary (lines read,
  128.  * error message) out as well. If the
  129.  * BACKUP conditional is set, then this routine also does the read
  130.  * end of backup processing. The BFBAK flag, if set in a buffer,
  131.  * says that a backup should be taken. It is set when a file is
  132.  * read in, but not on a new file (you don't need to make a backup
  133.  * copy of nothing).
  134.  *
  135.  * Warning: Adds a trainling nl to files that don't end in one!
  136.  * Need to fix, but later (I suspect that it will require a change
  137.  * in the fileio files for all systems involved).
  138.  */
  139. insertfile(fname, newname) char fname[], newname[]; {
  140.     register LINE    *lp1;
  141.     register LINE    *lp2;
  142.     LINE        *olp;            /* Line we started at */
  143.     int        opos;            /* and offset into it */
  144.     register WINDOW    *wp;
  145.     register int    i;
  146.     register int    nbytes;
  147.     int        s, nline;
  148.     BUFFER        *bp;
  149.     char        line[NLINE];
  150.  
  151.     bp = curbp;                /* Cheap.        */
  152.     if (newname != (char *) NULL)
  153.         (VOID) strcpy(bp->b_fname, newname);
  154.     if ((s=ffropen(fname)) == FIOERR)     /* Hard file open.    */
  155.         goto out;
  156.     if (s == FIOFNF) {            /* File not found.    */
  157.         if (kbdmop == NULL)
  158.             if (newname != NULL)
  159.                 ewprintf("(New file)");
  160.             else    ewprintf("(File not found)");
  161.         goto out;
  162.     }
  163.     opos = curwp->w_doto;
  164.     /* Open a new line, at point, and start inserting after it */
  165.     (VOID) lnewline();
  166.     olp = lback(curwp->w_dotp);
  167.     nline = 0;            /* Don't count fake line at end */
  168.     while ((s=ffgetline(line, NLINE)) == FIOSUC) {
  169.         nbytes = strlen(line);
  170.         if ((lp1=lalloc((RSIZE) nbytes)) == NULL) {
  171.             s = FIOERR;        /* Keep message on the    */
  172.             break;            /* display.        */
  173.         }
  174.         lp2 = lback(curwp->w_dotp);
  175.         lp2->l_fp = lp1;
  176.         lp1->l_fp = curwp->w_dotp;
  177.         lp1->l_bp = lp2;
  178.         curwp->w_dotp->l_bp = lp1;
  179.         for (i=0; i<nbytes; ++i)
  180.             lputc(lp1, i, line[i]);
  181.         ++nline;
  182.     }
  183.     (VOID) ffclose();            /* Ignore errors.    */
  184.     if (s==FIOEOF && kbdmop==NULL) {    /* Don't zap an error.    */
  185.         if (nline == 1)
  186.             ewprintf("(Read 1 line)");
  187.         else
  188.             ewprintf("(Read %d lines)", nline);
  189.     }
  190.     /* Set mark at the end of the text */
  191.     curwp->w_markp = curwp->w_dotp;
  192.     curwp->w_marko = curwp->w_doto;
  193.     /* Now, delete the results of the lnewline we started with */
  194.     curwp->w_dotp = olp;
  195.     curwp->w_doto = opos;
  196.     (VOID) ldelnewline();
  197.     curwp->w_doto = opos;            /* and dot is right    */
  198. #ifdef    BACKUP
  199.     if (newname != NULL)
  200.         bp->b_flag |= BFCHG | BFBAK;    /* Need a backup.    */
  201.     else    bp->b_flag |= BFCHG;
  202. #else
  203.     bp->b_flag |= BFCHG;
  204. #endif
  205.     /* if the insert was at the end of buffer, set lp1 to the end of
  206.      * buffer line, and lp2 to the beginning of the newly inserted
  207.      * text.  (Otherwise lp2 is set to NULL.)  This is 
  208.      * used below to set pointers in other windows correctly if they
  209.      * are also at the end of buffer.
  210.      */
  211.     lp1 = bp->b_linep;
  212.     if (curwp->w_markp == lp1)
  213.         lp2 = curwp->w_dotp;
  214.     else {
  215. out:        lp2 = NULL;
  216.     }
  217.     for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  218.         if (wp->w_bufp == curbp) {
  219.             wp->w_flag |= WFMODE|WFEDIT;
  220.             if (wp != curwp && lp2 != NULL) {
  221.                 if (wp->w_dotp == lp1)
  222.                     wp->w_dotp = lp2;
  223.                 if (wp->w_markp == lp1)
  224.                     wp->w_markp = lp2;
  225.                 if (wp->w_linep == lp1)
  226.                     wp->w_linep = lp2;
  227.             }
  228.         }
  229.     }
  230.     if (s == FIOERR)            /* False if error.    */
  231.         return (FALSE);
  232.     return (TRUE);
  233. }
  234.  
  235. /*
  236.  * Take a file name, and from it
  237.  * fabricate a buffer name. This routine knows
  238.  * about the syntax of file names on the target system.
  239.  * BDC1        left scan delimiter.
  240.  * BDC2        optional second left scan delimiter.
  241.  * BDC3        optional right scan delimiter.
  242.  */
  243. makename(bname, fname) char bname[]; char fname[]; {
  244.     register char    *cp1;
  245.     register char    *cp2;
  246.  
  247.     cp1 = &fname[0];
  248.     while (*cp1 != 0)
  249.         ++cp1;
  250. #ifdef    BDC2
  251.     while (cp1!=&fname[0] && cp1[-1]!=BDC1 && cp1[-1]!=BDC2)
  252.         --cp1;
  253. #else
  254.     while (cp1!=&fname[0] && cp1[-1]!=BDC1)
  255.         --cp1;
  256. #endif
  257.     cp2 = &bname[0];
  258. #ifdef    BDC3
  259.     while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=BDC3)
  260.         *cp2++ = *cp1++;
  261. #else
  262.     while (cp2!=&bname[NBUFN-1] && *cp1!=0)
  263.         *cp2++ = *cp1++;
  264. #endif
  265.     *cp2 = 0;
  266. }
  267.  
  268. /*
  269.  * Ask for a file name, and write the
  270.  * contents of the current buffer to that file.
  271.  * Update the remembered file name and clear the
  272.  * buffer changed flag. This handling of file names
  273.  * is different from the earlier versions, and
  274.  * is more compatable with Gosling EMACS than
  275.  * with ITS EMACS.
  276.  */
  277. /*ARGSUSED*/
  278. filewrite(f, n, k) {
  279.     register int    s;
  280.     char        fname[NFILEN];
  281.  
  282.     if ((s=ereply("Write file: ", fname, NFILEN)) != TRUE)
  283.         return (s);
  284.     adjustcase(fname);
  285.     if ((s=writeout(curbp, fname)) == TRUE) {
  286.         (VOID) strcpy(curbp->b_fname, fname);
  287. #ifdef    BACKUP
  288.         curbp->b_flag &= ~(BFBAK | BFCHG);
  289. #else
  290.         curbp->b_flag &= ~BFCHG;
  291. #endif
  292.         upmodes(curbp);
  293.     }
  294.     return (s);
  295. }
  296.  
  297. /*
  298.  * Save the contents of the current buffer back into
  299.  * its associated file. Do nothing if there have been no changes
  300.  * (is this a bug, or a feature). Error if there is no remembered
  301.  * file name. If this is the first write since the read or visit,
  302.  * then a backup copy of the file is made.
  303.  */
  304. /*ARGSUSED*/
  305. filesave(f, n, k) {
  306.     register int    s;
  307.  
  308.     if ((curbp->b_flag&BFCHG) == 0)    {    /* Return, no changes.    */
  309.         if (kbdmop == NULL) ewprintf("(No changes need to be saved)");
  310.         return (TRUE);
  311.     }
  312.     if (curbp->b_fname[0] == 0) {        /* Must have a name.    */
  313.         ewprintf("No file name");
  314.         return (FALSE);
  315.     }
  316. #ifdef    BACKUP
  317.     if ((curbp->b_flag&BFBAK) != 0) {
  318.         s = fbackupfile(curbp->b_fname);
  319.         if (s == ABORT)            /* Hard error.        */
  320.             return FALSE;
  321.         if (s == FALSE            /* Softer error.    */
  322.         && (s=eyesno("Backup error, save anyway")) != TRUE)
  323.             return (s);
  324.     }
  325. #endif
  326.     if ((s=writeout(curbp, curbp->b_fname)) == TRUE) {
  327. #ifdef    BACKUP
  328.         curbp->b_flag &= ~(BFCHG | BFBAK);
  329. #else
  330.         curbp->b_flag &= ~BFCHG;
  331. #endif
  332.         upmodes(curbp);
  333.     }
  334.     return (s);
  335. }
  336.  
  337. /*
  338.  * This function performs the details of file
  339.  * writing; writing the file in buffer bp to
  340.  * file fn. Uses the file management routines
  341.  * in the "fileio.c" package. Most of the grief
  342.  * is checking of some sort.
  343.  */
  344. writeout(bp, fn) register BUFFER *bp; char *fn; {
  345.     register int    s;
  346.     register LINE    *lp;
  347.  
  348.     if ((s=ffwopen(fn)) != FIOSUC)        /* Open writes message.    */
  349.         return (FALSE);
  350.     lp = lforw(bp->b_linep);        /* First line.        */
  351.     while (lp != bp->b_linep) {
  352.         if ((s=ffputline(&(ltext(lp))[0], llength(lp))) != FIOSUC)
  353.             break;
  354.         lp = lforw(lp);
  355.     }
  356.     if (s == FIOSUC) {            /* No write error.    */
  357.         s = ffclose();
  358.         if (s==FIOSUC && kbdmop==NULL)
  359.             ewprintf("Wrote %s", fn);
  360.     } else                    /* Ignore close error    */
  361.         (VOID) ffclose();        /* if a write error.    */
  362.     if (s != FIOSUC)            /* Some sort of error.    */
  363.         return (FALSE);
  364.     return (TRUE);
  365. }
  366.  
  367. /*
  368.  * Tag all windows for bp (all windows if bp NULL) as needing their
  369.  * mode line updated.
  370.  */
  371. upmodes(bp) register BUFFER *bp; {
  372.     register WINDOW    *wp;
  373.  
  374.     for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
  375.         if (bp == NULL || curwp->w_bufp == bp) wp->w_flag |= WFMODE;
  376. }
  377.  
  378.